
#include "usb_com.h"
#include "string.h"
#include "usbd_customhid.h"
#include "usb_device.h"

uint8_t report[CUSTOM_HID_EPOUT_SIZE];
const RecCmd recCmd[] =
{
    {COMM_UPDATE, COMM_SUB_UPDATE_BEGIN, update_begin},
    {COMM_UPDATE, COMM_SUB_UPDATE_DATA_SEND, update_send},
    {COMM_UPDATE, COMM_SUB_UPDATE_STOP, update_stop},
    {COMM_UPDATE, COMM_SUB_UPDATE_VERSION, update_version},
};



/// @brief 校验和
/// @param b 校验数组
/// @param len 校验长度
/// @return
unsigned char chksum(unsigned char *b, int len)
{
    unsigned char sum = 0;
    for (int i = 0; i < len; i++)
    {
        sum += b[i];
    }
    return sum;
}


/// @brief usb数据发送
/// @param arr 发送数组
/// @param len 发送长度
void usb_send(unsigned char *arr, unsigned short len)
{
    memset(report, 0, CUSTOM_HID_EPOUT_SIZE);
    memcpy(report, arr, len);
    USB_Send(report, CUSTOM_HID_EPOUT_SIZE);
}


/// @brief 串口接收
/// @param message
/// @param len
void usb_rec(unsigned char *message, unsigned short len)
{
    if (len < 6)
    {
        return;
    }
    else
    {
        if (!((message[0] == 0xaa && message[1] == 0x55) || (message[0] == 0x55 && message[1] == 0xaa)) || message[2] > len) //data len error or header error
        {
            return;
        }
        if (message[message[2] - 1] != chksum(message, message[2] - 1)) // checksum error
        {
            return;
        }

        for (int i = 0; i < sizeof(recCmd) / sizeof(RecCmd); i++) // 查找对应的命令
        {
            if (message[3] == recCmd[i].cmd && message[4] == recCmd[i].subCmd)
            {
                if (recCmd[i].recDeal)
                {
                    recCmd[i].recDeal(recCmd[i].cmd, recCmd[i].subCmd, message);
                }
                break;
            }
        }
    }
}


/// @brief 接收回复
/// @param ok
void usb_reply_ok(unsigned char cmd, unsigned char subCmd, void *ok)
{
    unsigned char reply[7];
    reply[0] = 0xaa;
    reply[1] = 0x55;
    reply[2] = 7;
    reply[3] = cmd;
    reply[4] = subCmd;
    reply[5] = (unsigned char)ok;
    reply[6] = chksum(reply, 6);
    usb_send(reply, 7);
}

 uint32_t fac_us=72000000/(int)1e6;//(本质：计算1us，SysTick的VAL寄存器减的数目, 1e6=1M ）
    /*详细解释：假设系统时钟为72M，那么Systick为系统时钟的八分频——9MHz，也就是每1s，VAL寄存器减去9M
      又因为1us=1/(1M)s，因此每1us，VAL寄存器减去fac_us = 9M/1M = 9
      即fac_us = SystemCoreClock/8/(int)1e6 = SystemCoreClock/(int)8e6;
    */

void delay_us(unsigned long nus)
{
    uint32_t told = SysTick->VAL; /* 刚进入时的计数器值 */
    uint32_t ticks;
    uint32_t tnow, tcnt = 0;
    uint32_t reload = SysTick->LOAD; /* LOAD 的值 */
    ticks = nus * fac_us-40; /* 需要的节拍数 减去指令补偿*/
    
    do{
        tnow = SysTick->VAL;
        //if (tnow != told)
        {
            tcnt += tnow < told?told - tnow:reload - tnow + told;
            told = tnow;
        }
    }while (tcnt < ticks);
}



